package com.best.developer.myarchitecturedemo.data.local.db;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.room.Room;
import android.content.Context;
import android.os.AsyncTask;


import com.best.developer.myarchitecturedemo.data.local.db.entity.Girl;
import com.best.developer.myarchitecturedemo.data.local.db.entity.ZhihuStory;

import java.util.ArrayList;
import java.util.List;

public class AppDatabaseManager {

    private static final String DATABASE_NAME = "architecture-practice-db";

    private final MutableLiveData<Boolean> mIsLoadingGirlList;

    private final MutableLiveData<Boolean> mIsLoadingZhihuList;

    private final MutableLiveData<List<Girl>> mGirlList;

    private final MutableLiveData<List<ZhihuStory>> mZhihuList;

    private static AppDatabaseManager INSTANCE = null;

    private AppDatabase mDB = null;


    /**
     * 构造代码块会先于无参构造和有参构造执行，所以里面一般放入必须要初始化的东西
     */
    {
        mIsLoadingGirlList = new MutableLiveData<>();
        mIsLoadingZhihuList = new MutableLiveData<>();
        mGirlList = new MutableLiveData<>();
        mZhihuList = new MutableLiveData<>();
    }

    private AppDatabaseManager() {
    }

    /**
     * 单例结构
     * @return
     */
    public static AppDatabaseManager getInstance() {
        if (INSTANCE == null) {
            synchronized (AppDatabaseManager.class) {
                if (INSTANCE == null) {
                    INSTANCE = new AppDatabaseManager();
                }
            }
        }
        return INSTANCE;
    }

    /**
     *  创建 database
     * @param context
     */
    public void createDB(Context context) {
        new AsyncTask<Context, Void, Void>() {
            @Override
            protected Void doInBackground(Context... params) {
                Context context = params[0].getApplicationContext();
                mDB = Room.databaseBuilder(context,
                        AppDatabase.class, DATABASE_NAME).build();
                return null;
            }
        }.execute(context.getApplicationContext());
    }

    /**
     * 插入 girls 数据
     * @param girls
     */
    public void insertGirlList(final List<Girl> girls) {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... voids) {
                mDB.beginTransaction();
                try {
                    mDB.girlDao().insertGirls(girls);
                    mDB.setTransactionSuccessful();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    mDB.endTransaction();
                }
                return null;
            }
        }.execute();

    }

    /**
     * 插入 ZhihuStory 数据
     * @param zhihuStoryList
     */
    public void insertZhihuList(final List<ZhihuStory> zhihuStoryList) {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... voids) {
                mDB.beginTransaction();
                try {
                    mDB.zhihuDao().insertZhihuList(zhihuStoryList);
                    mDB.setTransactionSuccessful();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    mDB.endTransaction();
                }
                return null;
            }
        }.execute();
    }

    /**
     * 加载 girl 集合
     * @return
     */
    public LiveData<List<Girl>> loadGirlList() {
        mIsLoadingGirlList.setValue(true);
        new AsyncTask<Void, Void, List<Girl>>() {

            /**
             * 从 database 中获取 girls
             * @param voids
             * @return
             */
            @Override
            protected List<Girl> doInBackground(Void... voids) {
                List<Girl> results = new ArrayList<>();
                //开启事务
                mDB.beginTransaction();
                try {
                    //在新集合中添加 girls 集合
                    results.addAll(mDB.girlDao().loadAllGirls());
                    //事务成功
                    mDB.setTransactionSuccessful();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    mDB.endTransaction();
                }
                return results;
            }

            /**
             * mGirlList 放入 girls
             * @param aVoid
             */
            @Override
            protected void onPostExecute(List<Girl> aVoid) {
                super.onPostExecute(aVoid);
                //设置false
                mIsLoadingGirlList.setValue(false);
                //在livedata集合中加入List<Girl>
                mGirlList.setValue(aVoid);
            }

            @Override
            protected void onCancelled(List<Girl> aVoid) {
                super.onCancelled(aVoid);
                mIsLoadingGirlList.setValue(false);
            }
        }.execute();
        return mGirlList;
    }


    /**
     * 加载 ZhihuStory 集合
     * @return
     */
    public LiveData<List<ZhihuStory>> loadZhihuList() {
        mIsLoadingZhihuList.setValue(true);
        new AsyncTask<Void, Void, List<ZhihuStory>>() {
            @Override
            protected List<ZhihuStory> doInBackground(Void... voids) {
                List<ZhihuStory> results = new ArrayList<>();
                mDB.beginTransaction();
                try {
                    results.addAll(mDB.zhihuDao().loadAllZhihus());
                    mDB.setTransactionSuccessful();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    mDB.endTransaction();
                }
                return results;
            }

            @Override
            protected void onPostExecute(List<ZhihuStory> aVoid) {
                super.onPostExecute(aVoid);
                mIsLoadingZhihuList.setValue(false);
                mZhihuList.setValue(aVoid);
            }

            @Override
            protected void onCancelled(List<ZhihuStory> aVoid) {
                super.onCancelled(aVoid);
                mIsLoadingZhihuList.setValue(false);
            }
        }.execute();
        return mZhihuList;
    }

    /**
     * 得到是否加载 girls 的布尔列表
     * @return
     */
    public LiveData<Boolean> isLoadingGirlList() {
        return mIsLoadingGirlList;
    }


    /**
     * 得到是否加载 Zhihu 的布尔列表
     * @return
     */
    public MutableLiveData<Boolean> isLoadingZhihuList() {
        return mIsLoadingZhihuList;
    }
}
